﻿
#region 文件信息
/*----------------------------------------------------------------
// 
// 文件名称：	
// 文件功能描述：	
// 设计要求：	
//
// 文 件 名：    SubscribeEventAttribute
// 创建者：      杨程
// 创建日期：	    2022/12/31 16:12:50

//----------------------------------------------------------------*/
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;



namespace Vampirewal.Core.EventBus;

/// <summary>
/// 订阅事件特性
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class SubscribeEventAttribute : Attribute
{
    /// <summary>
    /// 订阅事件特性
    /// </summary>
    public SubscribeEventAttribute(object token)
    {
        if (token is string)
        {
            Token = token as string;
        }
        else if (token is Enum)
        {
            Token = (token as Enum).GetDisplay();
        }
        else
        {
            throw new ArgumentException("不支持除字符串和枚举以外的token");
        }
    }

    public string Token { get; set; }

}

/// <summary>
/// 标记在事件总线中的方法才会执行
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class EventBusExcuteAttribute : Attribute
{
    /// <summary>
    /// 执行顺序
    /// </summary>
    public int ExcuteSort { get; set; } = 99;
}


/// <summary>
/// 事件工厂AOP特性，需继承
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public abstract class EventBusAOPAttribute : Attribute
{
    /// <summary>
    /// 方法执行前
    /// </summary>
    /// <param name="context">上下文</param>
    public abstract void ExcuteBefore(EventContext context);
    /// <summary>
    /// 方法执行后
    /// </summary>
    /// <param name="context">上下文</param>
    public abstract void ExcuteAfter(EventContext context);
}

internal static class EnumHelper
{
    /// <summary>
    /// 获取枚举的Display文本
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static String GetDisplay(this Enum value)
    {
        var type = value.GetType();//先获取这个枚举的类型
        var field = type.GetField(value.ToString());//通过这个类型获取到值
        var obj = (DisplayAttribute)field.GetCustomAttribute(typeof(DisplayAttribute));//得到特性
        return obj.Name ?? "";
    }
}


